Repository navigation
Reuse a program's descriptors after another program was drawn. - #435
Closed
SkippySteve wants to merge 1 commit into
Closed
SkippySteve wants to merge 1 commit into
SkippySteve wants to merge 1 commit into
Conversation
A draw kept descriptors only when it repeated the previous draw's program. Binding another program dropped them, so almost every draw built its set again. The set is kept per program and pushed again when that program returns, unless a binding, a registration, a mirror, or a uniform update it read has changed.
Owner
|
Closing to keep the queue clear — please rebase on current main and reopen; thanks! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Steady play on an RTX 2060 SUPER (driver 615.78.08) was about 32 fps, 1425 draws a frame. Replay of one of those frames spent 14.13 ms before the queue submit. The largest piece was descriptors, 4.42 ms. Programs were 1.56 ms and the command recording 3.40 ms. The GPU's own time was 14.8 ms.
A draw kept its descriptors only when it was the same program as the draw before it, with the same bindings. About 7 draws a frame took that path. Binding another program bumped the binding generation even when the textures, uniform buffers and samplers were unchanged, so the set was built again on the way back. There were about 80 uniform updates a frame (56 of them stream copies), not one per draw, so the bindings themselves were mostly stable.
Change
A program's descriptor writes are kept and pushed again when that program is drawn after another one. The push still happens, because the command buffer is holding the other program's set. The following draw of the same program still takes the existing neighbour path and skips the push.
The kept set is dropped when any of these changed:
RX_VK_NO_DESC_REUSE=1still builds every draw. Dump, probe and the stats frame do too, and they do not store a set. The frame log gains a line,draws reused a program's descriptors, beside the existing neighbour line.Why this is safe
A miss rebuilds, which is what every draw did before. A hit restores the writes from the build and repeats the side effects that build had: storage images are marked written, storage buffers the program writes are stamped, and sampled textures are hazarded from whether they are GPU-written now. The recording's upload stream is only appended to until the next recording, and the kept sets are dropped when that recording starts. A masked clear still pushes the whole set again; it does not drop the copy.
Testing
Game-free, the same way CI runs them:
python -I -B tests/test_desc_prog.pypython -I -B tests/test_same_bind.pypython -I -B tests/test_ub_gap.pypython -I -B tests/test_ub_memo.pypython -I -B tests/test_vertex_bind.pypython -I -B tests/test_desc_clock.pypython -I -B tests/test_dispatch_clock.pypython -I -B tests/test_table_track.pypython -I -B tests/test_same_draw.pypython -I -B tests/test_same_dyn.pypython -I -B tests/test_pass_hazard.pypython -I -B tests/test_handle_lookup.pyNegative control: with the source change put aside and the new test kept,
tests/test_desc_prog.pyfailed (descriptors have no generation of their own). Restoring the change made it pass.This was not playtested, and fps was not remeasured. The numbers above are from a run before this change.
Scope
This does not include the vertex and index bind skip in #423, pipeline manifests, or further submit batching. Happy to rename the log line or split the test if that reads better.